package com.ihr360.shared.sequence.handler;

import com.ihr360.commons.annotation.CodeGenerator;
import com.ihr360.commons.exception.Ihr360Exception;
import com.ihr360.commons.lang.Ihr360EntityUtils;
import com.ihr360.commons.lang.StringUtils;
import com.ihr360.context.SpringContext;
import com.ihr360.shared.sequence.service.CodeGeneratorService;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.persistence.PrePersist;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

public class CodeGeneratorHandler {
    Logger logger = LoggerFactory.getLogger(CodeGeneratorHandler.class);
    private static final Class codeGeneratorClazz = CodeGenerator.class;
    CodeGeneratorService service;

    @PrePersist
    void onPrePersist(Object o) {
        if (o == null) {
            return;
        }
        if (service == null) {
            service = SpringContext.getBean(CodeGeneratorService.class);
        }

        List<Field> fieldList = Ihr360EntityUtils.getFieldsWithAnnotation(o, codeGeneratorClazz);
        if (CollectionUtils.isEmpty(fieldList)) {
            return;
        }
        for (Field field : fieldList) {
            CodeGenerator codeGenerator = (CodeGenerator) field.getAnnotation(codeGeneratorClazz);
            String bizModel = codeGenerator.bizModel();
            if (StringUtils.isBlank(bizModel)) {
                bizModel = o.getClass().getSimpleName();
            }
            try {
                //对于已经进行了赋值的code,不进行重新赋值操作
                String proValue = BeanUtils.getProperty(o, field.getName());

                boolean isPrimitive = field.getType().isPrimitive();
                boolean isInt = false;
                if (isPrimitive) {
                    isInt = field.getType().getName().equals("int");
                }
                
                if (StringUtils.isNotEmpty(proValue) && !isInt) {
                    continue;
                }
                if (isInt && !"0".equals(proValue)) {
                    continue;
                }
            } catch (Exception e) {
                if (logger.isWarnEnabled()) {
                    logger.warn(e.getMessage(), e);
                }
                continue;
            }
            try {
                int maxLength = codeGenerator.maxLength();
                String code = service.generate(codeGenerator, o);
                if (StringUtils.isEmpty(code)) {
                    return;
                }
                if (code.length() > maxLength) {
                    throw new Ihr360Exception(null, codeGenerator.name() + "已超过长度上限" + maxLength + "个字符，请重新设置流水号规则。");
                }
                BeanUtils.copyProperty(o, field.getName(), code);
            } catch (IllegalAccessException e1) {
                if (logger.isWarnEnabled()) {
                    logger.warn(e1.getMessage(), e1);
                }
                throw new Ihr360Exception(null, "序列号赋值错误");
            } catch (InvocationTargetException e2) {
                if (logger.isWarnEnabled()) {
                    logger.warn(e2.getMessage(), e2);
                }
                throw new Ihr360Exception(null, "序列号赋值错误");
            }
        }
        logger.info(o.toString());
    }
}